package com.cc.dy.executer;

import cn.hutool.core.lang.Assert;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.cc.dy.api.DyAuthService;
import com.cc.dy.api.DyPayService;
import com.cc.dy.api.DyUserService;
import com.cc.dy.api.impl.DyAuthServiceImpl;
import com.cc.dy.api.impl.DyPayServiceImpl;
import com.cc.dy.api.impl.DyUserServiceImpl;
import com.cc.dy.config.DyConfig;
import com.cc.dy.enums.DyErrorCode;
import com.cc.dy.enums.EnvEnum;
import com.cc.dy.http.DyHttpClient;
import com.cc.dy.http.impl.OkHttpDyHttpClient;
import com.cc.dy.storage.StorageService;
import com.cc.dy.storage.impl.RedisStorageService;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 接口基类
 *
 * <pre>
 * 处理请求与accessToken 处理
 * </pre>
 */
@Setter
@Getter
public abstract class AbstractDyService implements DyService {
    private EnvEnum envEnum = EnvEnum.PRODUCTION;
    private StorageService storageService;
    private DyHttpClient dyHttpClient = new OkHttpDyHttpClient(this);
    private DyPayService dyPayService = new DyPayServiceImpl(this);
    private DyAuthService dyAuthService = new DyAuthServiceImpl(this);
    private DyUserService dyUserService = new DyUserServiceImpl(this);
    private Map<String, DyConfig> dyConfigStorageMap = new ConcurrentHashMap<>();
    private ThreadLocal<DyConfig> dyConfigStorageThreadLocal = new TransmittableThreadLocal<>();

    public AbstractDyService() {
    }

    public AbstractDyService(RedisTemplate<String, String> redisTemplate) {
        this.storageService = new RedisStorageService(redisTemplate);
    }

    /**
     * 切换客户端
     *
     * @param clientId 客户端id
     */
    @Override
    public void switchClient(String clientId) {
        DyConfig dyConfig = dyConfigStorageMap.get(clientId);
        Assert.notNull(dyConfig, DyErrorCode.ERROR_CONFIG_NOT_EXIST);
        dyConfigStorageThreadLocal.set(dyConfig);
    }

    /**
     * 添加小程序配置信息
     *
     * @param dyConfig 小程序配置信息
     */
    @Override
    public void addDyConfig(DyConfig dyConfig) {
        dyConfigStorageMap.put(dyConfig.getAppId(), dyConfig);
    }

    /**
     * 获取当前小程序配置
     *
     * @return 小程序配置
     */
    @Override
    public DyConfig getDyConfig() {
        return dyConfigStorageThreadLocal.get();
    }

    /**
     * 设置当前环境
     *
     * @param env 环境
     */
    @Override
    public void setEnv(EnvEnum env) {
        envEnum = env;
    }

    /**
     * 获取当前环境
     *
     * @return 环境
     */
    @Override
    public EnvEnum getEnv() {
        return envEnum;
    }
}
